#include "widget.h"
#include "ui_widget.h"
#include "tcpclient.h"
#include <QHostInfo>
#include <QMessageBox>
#include <QScrollBar>
#include <QDateTime>
#include <QNetworkInterface>
#include <QProcess>
#include <QFileDialog>

Widget::Widget(QWidget *parent)
    : QWidget(parent)
    , ui(new Ui::Widget)
{
    ui->setupUi(this);
    udpSocket = new QUdpSocket(this);
    port = 45454;
    udpSocket->bind(port, QUdpSocket::ShareAddress | QUdpSocket::ReuseAddressHint);
    connect(udpSocket, SIGNAL(readyRead()), this, SLOT(processPendingDatagrams()));
    // 广播用户登录消息
    sendMessage(NewParticipant);

    // tcp文件传输服务
    server = new TcpServer(this);
    connect(server, SIGNAL(sendFileName(QString)), this, SLOT(getFileName(QString)));
}

Widget::~Widget()
{
    delete ui;
}

void Widget::newParticipant(QString username, QString localHostName, QString idAddress)
{
    // 新用户加入
    bool isEmpty = ui->userTableWidget->findItems(localHostName, Qt::MatchExactly).isEmpty();
    if (isEmpty) {
        QTableWidgetItem *user = new QTableWidgetItem(username);
        QTableWidgetItem *host = new QTableWidgetItem(localHostName);
        QTableWidgetItem *ip = new QTableWidgetItem(idAddress);

        ui->userTableWidget->insertRow(0);
        ui->userTableWidget->setItem(0, 0, user);
        ui->userTableWidget->setItem(0, 1, host);
        ui->userTableWidget->setItem(0, 2, ip);

        ui->messageBrowser->setTextColor(Qt::gray);
        ui->messageBrowser->setCurrentFont(QFont("Times New Roman", 10));
        ui->messageBrowser->append(tr("%1在线！").arg(username));

        ui->userNumLabel->setText(tr("在线人数：%1").arg(ui->userTableWidget->rowCount()));

        sendMessage(NewParticipant);
    }
}

void Widget::participantLeft(QString username, QString localHostName, QString time)
{
    // 用户离开
    int rowNum = ui->userTableWidget->findItems(localHostName,Qt::MatchExactly).first()->row();

    ui->userTableWidget->removeRow(rowNum);

    ui->messageBrowser->setTextColor(Qt::gray);
    ui->messageBrowser->setCurrentFont(QFont("Time New Roman"));
    ui->messageBrowser->append(tr("%1与%2离开！").arg(username).arg(time));
    ui->userNumLabel->setText(tr("在线人数：%1").arg(ui->userTableWidget->rowCount()));
}

void Widget::sendMessage(MessageType type, QString serverAddress)
{
    QByteArray data;
    QDataStream out(&data, QIODevice::WriteOnly);
    // 获取本地主机名
    QString localHostName = QHostInfo::localHostName();
    // 获取IP
    QString address = getIP();
    // 写入信息
    out << type << getUsername() << localHostName;

    // 判断消息类型
    switch (type) {
    case Message:{
        if (ui->messageTextEdit->toPlainText() == "") {
            QMessageBox::warning(0, "警告", "发送内容不能为空", QMessageBox::Ok);
            return;
        }
        out << address << getMessage();
        ui->messageBrowser->verticalScrollBar()->setValue(
            ui->messageBrowser->verticalScrollBar()->maximum());
        break;
    }
    case NewParticipant:
        out << address;
        break;
    case ParticipantLeft:
        break;
    case Filename:{
        int row = ui->userTableWidget->currentRow();
        QString clientAddress = ui->userTableWidget->item(row, 2)->text();
        out << address << clientAddress << fileName;
        break;
    }
    case Refuse:
        out << serverAddress;
        break;
    }

    udpSocket->writeDatagram(data, data.length(), QHostAddress::Broadcast, port);
}

QString Widget::getIP()
{
    // 获取系统IP地址
    QList<QHostAddress> list = QNetworkInterface::allAddresses();
    foreach (QHostAddress address, list) {
        if (address.protocol() == QAbstractSocket::IPv4Protocol)
            return address.toString();
    }
    return 0;
}

QString Widget::getUsername()
{
    // 获取系统用户名
    QStringList envVariables;
    envVariables << "USERNAME.*" << "USER.*" << "USERDOMAIN.*" << "HOSTNAME.*" << "DOMAINNAME.*";
    // 获取系统环境变量
    QStringList environment = QProcess::systemEnvironment();
    foreach (QString string, envVariables) {
        // 正则匹配
        int index = environment.indexOf(QRegularExpression(string));
        if (index != -1) {
            QStringList stringList = environment.at(index).split('=');
            if (stringList.size() == 2) {
                return stringList.at(1);
                break;
            }
        }
    }
    return "unknown";
}

QString Widget::getMessage()
{
    // 提取输入框内容
    QString msg = ui->messageTextEdit->toHtml();
    ui->messageTextEdit->clear();
    ui->messageTextEdit->setFocus();
    return msg;
}

void Widget::hasPendingFile(QString userName, QString serverAddress, QString clientAddress, QString fileName)
{
    QString ipAddress = getIP();
    if (ipAddress == clientAddress) {
        int btn = QMessageBox::information(this, "接受文件",
                                           tr("来自%1（%2）的文件：%3，是否接收？")
                                               .arg(userName)
                                               .arg(serverAddress)
                                               .arg(fileName),
                                           QMessageBox::Yes, QMessageBox::No);
        if (btn == QMessageBox::Yes) {
            QString name = QFileDialog::getSaveFileName(0, "保存文件", fileName);
            if (!name.isEmpty()) {
                TcpClient *client = new TcpClient(this);
                client->setFileName(name);
                client->setHostAddress(QHostAddress(serverAddress));
                client->show();
            }
        } else {
            sendMessage(Refuse, serverAddress);
        }
    }
}

void Widget::getFileName(QString name)
{
    // 获取文件名并发送信息
    fileName = name;
    sendMessage(Filename);
}

void Widget::processPendingDatagrams()
{
    // 处理接收的消息
    while(udpSocket->hasPendingDatagrams()) {
        QByteArray datagram;
        datagram.resize(udpSocket->pendingDatagramSize());

        udpSocket->readDatagram(datagram.data(), datagram.size());

        QDataStream in(&datagram, QIODeviceBase::ReadOnly);

        int messageType;
        in >> messageType;
        QString userName, localHostName, ipAddress, message;
        QString time=  QDateTime::currentDateTime().toString("yyyy-MM-dd hh:mm:ss");
        switch (messageType) {
        case Message:{
            in >> userName >> localHostName >> ipAddress >> message;
            ui->messageBrowser->setTextColor(Qt::blue);
            ui->messageBrowser->setCurrentFont(QFont("Times New Roman", 12));
            ui->messageBrowser->append("[" + userName + "]" + time);
            ui->messageBrowser->append(message);
            break;
        }
        case NewParticipant:
            in >> userName >> localHostName >> ipAddress;
            newParticipant(userName, localHostName, ipAddress);
            break;
        case ParticipantLeft:
            in >> userName >> localHostName;
            participantLeft(userName, localHostName, time);
        case Filename:{
            in >> userName >> localHostName >> ipAddress;
            QString clientAddress, fileName;
            in >> clientAddress >> fileName;
            hasPendingFile(userName, ipAddress, clientAddress, fileName);
            break;
        }
        case Refuse:{
            in >> userName >> localHostName;
            QString serverAddress;
            in >> serverAddress;
            QString ipAddress = getIP();
            if (ipAddress == serverAddress)
                server->refused();
            break;
        }
        }
    }
}


void Widget::on_sendButton_clicked()
{
    // 发送消息
    sendMessage(Message);
}


void Widget::on_sendToolBtn_clicked()
{
    if (ui->userTableWidget->selectedItems().isEmpty()) {
        QMessageBox::warning(0, "选择用户", "请先选择用户列表选择要发送的用户！", QMessageBox::Ok);
        return;
    }
    // 打开文件传输窗口
    server->show();
    server->initServer();
}

